"""
此脚本用于获取指定xts仓所涉及的部件仓
XTS_SUITE[]:指定需计算的xts仓,支持列表
CODE_ROOT:全量代码根目录
对应流程:
xts:part_name -> repo_path -> 仓名
"""
import os
import re
import json
import xml.etree.ElementTree as ET

XTS_SUITE = [
    "acts"
]

HOME = os.path.dirname(os.path.abspath(__file__))

MANIFEST_HOME = os.path.join(HOME, ".repo", "manifests")

XTS_HOME = os.path.join(HOME, "test", "xts")

JSON_FILE = os.path.join(HOME, "test", "xts", "tools", "config", "precise_compilation.json")


def get_bundle_name_bypath(path):
    bundle_path = os.path.join(path,"bundle.json")
    if os.path.exists(bundle_path):
        with open(bundle_path, 'r') as json_file:
            data = json.load(json_file)
            # 尝试获取 "component" 对象里的 "name" 字段
            component = data.get("component")
            if component and isinstance(component, dict):
                component_name = component.get("name")
                # 如果找到了 "name" 字段，返回
                if component_name:
                    return component_name
    return None


"""
    遍历manifest,获取 路径-repo对应的map
"""
bundle_error_map = {}

def get_bundle_path_repo_map_impl (manifest_home, bundle_path_repo_map):
    # print(manifest_home)
    # 遍历XML文件内容
    manifest_xml_list = [manifest_home]
    for xml in manifest_xml_list:
        root = ET.parse(xml).getroot()
        if root.find('include') is not None:
            # print ("in include")
            for child in root.findall('include'):
                get_bundle_path_repo_map_impl(os.path.join(MANIFEST_HOME, child.attrib['name']), bundle_path_repo_map)
        else:
            # print ("in else")
            for child in ET.parse(xml).getroot().findall('project'):
                if "lite" in child.attrib['path']:
                    continue
                repo_name = child.attrib['name']
                path = child.attrib['path']
                bundle_name = get_bundle_name_bypath(path)
                if bundle_name is None:
                    bundle_error_map[path] = [repo_name,"bundle.json获取失败"]
                else:
                    bundle_path_repo_map[bundle_name] = [path,repo_name]

def get_bundle_path_repo_map (manifest_home):
    bundle_path_repo_map = {}
    get_bundle_path_repo_map_impl(manifest_home, bundle_path_repo_map)
    return bundle_path_repo_map

def get_allpartname (xts_path):
    part_names = set()
    part_name_pattern = re.compile(r'part_name\s*=\s*"([^"]+)"')
    for dirpath, dirnames, filenames in os.walk(xts_path):
        for filename in filenames:
            if filename == "BUILD.gn":
                gn_files = os.path.join(dirpath, filename)
                with open(gn_files, 'r') as file:
                    content = file.read()
                    match = part_name_pattern.search(content)
                    if match:
                        part_names.add(match.group(1))
    return list(part_names)

def run():
    # 遍历manifest,获取 路径-repo对应的map
    # bundle_path_repo_map[bundle_name] = [path,bundle_name]
    bundle_path_repo_map = get_bundle_path_repo_map(os.path.join(os.path.dirname(MANIFEST_HOME), "manifest.xml"))
    print(bundle_error_map)
    # 根据path_repo_map到对应path查找bundle
    xts_repo = {}
    for xts in XTS_SUITE:
        xts_repo[xts] = []
        current_xts = os.path.join(XTS_HOME, xts)
        # 获取当前xts下全部part_name
        part_names = get_allpartname(current_xts)
        for part_name in part_names:
            if part_name in bundle_path_repo_map:
                xts_repo[xts].append(bundle_path_repo_map[part_name][1])
            else:
                bundle_error_map[part_name] = ["不存在本bundle_name"]

    xts_repo_json_file = './xts_repo.json'
    bundle_error_json_file = './error_repo.json'
    # 将字典写入JSON文件
    with open(xts_repo_json_file, 'w', encoding='utf-8') as json_file:
        json.dump(xts_repo, json_file, ensure_ascii=False, indent=4)
    with open(bundle_error_json_file, 'w', encoding='utf-8') as json_file:
        json.dump(bundle_error_map, json_file, ensure_ascii=False, indent=4)

if __name__ == '__main__':
    run()
